package com.scau.clothes.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.scau.clothes.dao.OrderClothesDao;
import com.scau.clothes.dao.OrderDao;
import com.scau.clothes.pojo.Clothes;
import com.scau.clothes.pojo.Order;
import com.scau.clothes.pojo.OrderClothes;
import com.scau.clothes.service.CartService;
import com.scau.clothes.service.ClothesService;
import com.scau.clothes.service.ClothesStockService;
import com.scau.clothes.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    ClothesService clothesService;
    @Autowired
    ClothesStockService clothesStockService;
    @Autowired
    OrderClothesDao orderClothesDao;
    @Autowired
    OrderDao orderDao;
    private static String CART = "CART";
    private static String ORDER = "ORDER";
    private static String ORDER_CLOTHES = "ORDER_CLOTHES";
    private static String CLOTHES = "CLOTHES";
    @Override
    public  List<OrderClothes> getOCByUserIdInRedis(int id) {
        List<Object> ocList = redisTemplate.opsForHash().values(CART + id);
        if(ocList == null){
            return null;
        }
        List<OrderClothes> res = new LinkedList<>();
        Iterator<Object> iterator = ocList.iterator();
        while(iterator.hasNext()){
            String ocJSON = (String) iterator.next();
            OrderClothes oc = JSONObject.parseObject(ocJSON, OrderClothes.class);
            res.add(oc);
        }
        return res;
    }
    @Override
    public void addClothesToCartByUserId(int userId,int clothesId,int num) {
        OrderClothes oc = createOCByClothesId(clothesId,num);
        String ocJSON = JSONObject.toJSONString(oc);
        if (!redisTemplate.opsForHash().putIfAbsent(CART+userId,CLOTHES+clothesId,ocJSON)) {
            ocJSON  = (String) redisTemplate.opsForHash().get(CART + userId, CLOTHES+clothesId);
            OrderClothes oldOC = JSONObject.parseObject(ocJSON, OrderClothes.class);
            oldOC.setActualTotalPrice(oldOC.getActualTotalPrice().add(oc.getActualTotalPrice()));
            oldOC.setTotalPrice(oldOC.getTotalPrice().add(oc.getTotalPrice()));
            oldOC.setNum(oldOC.getNum()+oc.getNum());
            ocJSON = JSONObject.toJSONString(oldOC);
            redisTemplate.opsForHash().put(CART+userId,CLOTHES+clothesId,ocJSON);
        }
    }

    @Override
    public void deleteClothesFromCartBy1(int userId, int clothesId) {
        String ocJSON = (String) redisTemplate.opsForHash().get(CART + userId, CLOTHES + clothesId);
        OrderClothes oc = JSONObject.parseObject(ocJSON, OrderClothes.class);
        if(oc.getNum()==1){
            redisTemplate.opsForHash().delete(CART+userId,CLOTHES+clothesId);
            return;
        }
        oc.setActualTotalPrice(oc.getActualTotalPrice().subtract(oc.getActualTotalPrice().divide(BigDecimal.valueOf(oc.getNum()))));
        oc.setTotalPrice(oc.getTotalPrice().subtract(oc.getTotalPrice().divide(BigDecimal.valueOf(oc.getNum()))));
        oc.setNum(oc.getNum()-1);
        ocJSON = JSONObject.toJSONString(oc);
        redisTemplate.opsForHash().put(CART+userId,CLOTHES+clothesId,ocJSON);
    }

    private OrderClothes createOCByClothesId(Integer clothesId,int num) {
        Clothes clothes = clothesService.getClothesById(clothesId);
        OrderClothes oc = new OrderClothes();
        oc.setNum(num);
        oc.setClothesId(clothesId);
        oc.setUnitPrice(clothes.getPrice());
        oc.setTotalPrice(clothes.getPrice().multiply(BigDecimal.valueOf(num)));
        if(clothes.getPromotionStatus()==0||(clothes.getPromotionStatus()==1&&clothes.getPromotionPrice().equals(BigDecimal.valueOf(0)))){
            oc.setUnitActualPrice(clothes.getPrice());
        }
        else{
            oc.setUnitActualPrice(clothes.getPromotionPrice());
        }
        oc.setActualTotalPrice(oc.getUnitActualPrice().multiply(BigDecimal.valueOf(num)));
        return oc;
    }


    @Override
    public void insertOCList(List<OrderClothes> ocList) {
        orderClothesDao.insertOCList(ocList);
    }

    @Override
    public void insertOC(OrderClothes oc) {
        orderClothesDao.insertOC(oc);
    }

    @Override
    public void updateOC(OrderClothes oc) {
        orderClothesDao.updateOC(oc);
    }

    @Override
    public List<OrderClothes> getOCByOrderId(int orderId) {
        return orderClothesDao.getOCByOrderId(orderId);
    }
}
